package edu.pku.sei.mte.mtemodel.mtmodel.expression;

import java.util.ArrayList;
import java.util.List;

import edu.pku.sei.mte.runtime.Context;
import edu.pku.sei.mte.utilities.Visitor;

abstract public class CallRuleExpression extends Expression {
	private List<Expression> parentPart;
	private List<Expression> childPart;
	protected String ruleName;

	public void collectReferedProperty(String root, List<String> coll) {
		return;
	}

	public List<Expression> getChildPart() {
		if(childPart==null){
			childPart = new ArrayList<Expression>();
		}
		return childPart;
	}

	public List<Expression> getParentPart() {
		if(parentPart==null){
			parentPart = new ArrayList<Expression>();
		}
		return parentPart;
	}
	
	public void setParameter(Expression parentPartExpression,Expression childPartExpression){
		getParentPart().add(parentPartExpression);
		getChildPart().add(childPartExpression);
	}

	protected boolean setup(Context pc, Context cc, boolean enforce) {
		List<Expression> parent = getParentPart();
		List<Expression> child = getChildPart();
		
		int i,s = parent.size();
		
		for(i=0;i<s;i++){
			Expression pe = parent.get(i);
			Expression ce = child.get(i);
			
			Object pv = pe.evaluate(pc, false);
			if(pv!=Expression.ERROR_VALUE&&pv!=Expression.UNINITIATED_VALUE){
				ce.evaluate(cc, false, pv);
			} else if(enforce)//some parameters haven't been setup correctly
				return false;
		}
		return true;
	}

	protected boolean setdown(Context pc, Context cc, boolean enforce) {
		List<Expression> parent = getParentPart();
		List<Expression> child = getChildPart();
		
		int i,s = parent.size();
		for(i=0;i<s;i++){
			Expression pe = parent.get(i);
			Expression ce = child.get(i);
			
			Object cv = ce.evaluate(cc, false);
			if(cv!=Expression.ERROR_VALUE){
				pe.evaluate(pc, false, cv);
			}
		}
		return true;
	}

	public String getRuleName() {
		return ruleName;
	}

	public void setRuleName(String ruleName) {
		this.ruleName = ruleName;
	}

	@Override
	public Object accept(Visitor visitor) throws Exception {
		return visitor.visitCallRuleExpression(this);
	}
}
